#ifndef GROUP_H 
#define GROUP_H

#include <map>
#include <list>
#include "Vertex.h"
#include "VertexSet.h"
#include "VertexDirectory.h"
#include "VertexBase.h"

using std::list;
using std::map;

typedef vector<bool>							VertexKey;
typedef list<Vertex*>::iterator					ListIterator;
typedef map<VertexKey, ListIterator*>::iterator	MapIterator;


class Group: public VertexContainer 
{
public:
	Group(int name, VertexDirectory* dir = NULL);
	Group(Group& groupToCopy, VertexDirectory* dir = NULL);
	void Clone(Group& groupToCopy); //deep copy, vertex pointers taken from static vertex directory
	~Group();
	int Size();
	int GetGroupName();
	string PrintName();
	int SetGroupName(int newName);
	void InsertNewVertex(VertexBase* vertexBase);
	void InsertVertex(Vertex* vertex);
	void InsertNewVertexCouple(VertexSet* vertices);
	void RemoveVertex(Vertex* vertex);		//shuld be in Vertex container?
	void RemoveVertexSet(VertexSet *vertexSet);
	void RemoveVertexBase(VertexBase *vertexBase);
	bool IsVertexInGroup(VertexKey vertex);
	bool IsVertexCoupleInGroup(VertexSet* vertices);
	bool IsVertexBaseInGroup(VertexBase* vertex);
	bool IsLegalToAdd(VertexBase* vertex, bool makeInterchangeableChecks = false);
	bool IsLegalToAdd(pair<Vertex*, Vertex*> &vertexPair, bool makeInterchangeableChecks = false);
	Group* BreakGroup(double percent, list<Vertex*>* thrownVertices , VertexDirectory* newGroupDirectory = NULL);
	list<Vertex*>::iterator Iterator();
	bool End(list<Vertex*>::iterator it);
	void SetGroupVertexDirectory(VertexDirectory* dir);
	void UpdateContainerForGroupVertices();
	list<VertexKey> VerticesNames();	
	list<Vertex*>::iterator Find(VertexKey vertexName);
	list<Vertex*>* GetGroupVertices();
	void Print();
	void PairUpVerticesAndFindReplacements(Graph *graph);

private:
	list<Vertex*>					m_VerticesQueue;
	map<VertexKey, ListIterator*>	m_VerticesMap;
	int								m_GroupName;
	
	// points to the directory this group will use. if NULL - static directory used
	VertexDirectory*                m_Directory;
};


#endif //GROUP_H